package model;

import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

/**
 * 
 * @author Martin Sax og Daniel Engel
 * 
 */
@Entity
public class MellemVare extends ProduktType {

	private long vareNummer;

	@OneToMany(cascade = CascadeType.PERSIST)
	@JoinColumn(nullable = true)
	private List<TimeStamp> startTidListe;

	private int naesteDelbehandling;

	/**
	 * Initialisere en mellemvare
	 * 
	 * @param navn
	 *            , navnet på den pågældende mellemvare
	 * @param behandling
	 *            , den aktuelle behandling for den pågældende mellemvare
	 * @param vareNummer
	 *            , varenummeret på den pågældende mellemvare
	 */
	public MellemVare(String navn, Behandling behandling, long vareNummer) {
		super(navn, behandling);
		startTidListe = new ArrayList<TimeStamp>();
		this.vareNummer = vareNummer;
		naesteDelbehandling = 0;
		nextDelBehandling();
	}

	/**
	 * tom constructer som bruges af JPA
	 */
	public MellemVare() {

	}

	/**
	 * toString metode som formatere visningen af den aktuelle mellemvare.
	 */
	public String toString() {
		return vareNummer + " (" + super.getNavn() + ")";
	}

	/**
	 * Sætter varenummeret på den aktuelle mellemvare
	 * 
	 * @param vareNummer
	 *            , Mellemvares varenummer.
	 */
	public void setVareNummer(long vareNummer) {
		this.vareNummer = vareNummer;
	}

	/**
	 * Denne metode retunerer varenummeret på den aktuelle mellemvare.
	 * 
	 * @return den aktuelle mellemvares varenummer.
	 */
	public long getVareNummer() {
		return vareNummer;
	}

	/**
	 * @auther Martin sax Sender mellemvaren videre til næste delbehandling ved
	 *         at tilføje timestamps til et array. og adderer en til
	 *         naesteDelbehandling-fieldet.
	 */
	public void nextDelBehandling() {
		if (naesteDelbehandling < getAllTimeStamp().length - 1) {
			startTidListe.add(new TimeStamp(this.getBehandling()
					.getDelBehandlinger().get(naesteDelbehandling)));
			naesteDelbehandling++;
		} else if (naesteDelbehandling == getAllTimeStamp().length - 1) {
			startTidListe.add(new TimeStamp(this.getBehandling()
					.getDelBehandlinger().get(naesteDelbehandling - 1)));
			naesteDelbehandling++;
		} else {
			throw new RuntimeException("Dette produkt er sendt til pakning");
		}
	}

	/**
	 * @author Martin Sax
	 * @return rasterende tid der skal gå før varen må tages vidre til næste del
	 *         behandling Krav: den nuværende del behandling skal være af typen
	 *         DelBehandlingTorretid
	 */
	public int getMinTidTilbage() {
		return (int) (new GregorianCalendar().getTimeInMillis() - (getAllTimeStamp()[naesteDelbehandling - 1]
				.getStartTidsPunkt().getTimeInMillis() + ((DelBehandlingTorreTid) getAllTimeStamp()[naesteDelbehandling - 1]
				.getDelBehandling()).getMinTid() * 1000)) / 1000;

	}

	/**
	 * @author Martin Sax
	 * @return hvor tæt man er på det ideelle tidspunkt for denne delbehandling
	 *         Krav: den nuværende del behandling skal være af typen
	 *         DelBehandlingTorretid
	 */
	public int getIdeelTid() {
		return (int) (new GregorianCalendar().getTimeInMillis() - (getAllTimeStamp()[naesteDelbehandling - 1]
				.getStartTidsPunkt().getTimeInMillis() + ((DelBehandlingTorreTid) getAllTimeStamp()[naesteDelbehandling - 1]
				.getDelBehandling()).getIdeelTid() * 1000)) / 1000;
	}

	/**
	 * @author Martin Sax
	 * @return rasterende tid før varen skal kasseres.
	 */
	public int getMaxTidTilbage() {
		return (int) (((getAllTimeStamp()[naesteDelbehandling - 1]
				.getStartTidsPunkt().getTimeInMillis() + (getAllTimeStamp()[naesteDelbehandling - 1]
				.getDelBehandling()).getMaxTid() * 1000)) - new GregorianCalendar()
				.getTimeInMillis()) / 1000;
	}

	/**
	 * retunere det nuværende timestamp
	 * 
	 * @return, varens nuværende timestamp.
	 */
	public TimeStamp getTimeStamp() {
		return getAllTimeStamp()[naesteDelbehandling - 1];
	}

	/**
	 * @author Martin Sax 
	 * 		   Fylder listen startTidListe i et Array, dette gøres
	 *         pga. jqdb ikke kan håndtere Arrays og vi har brugt array
	 *         metoder("getAllTimeStamps().length og getAllTimeStamps()[]") oppe
	 *         i vores gui
	 * @return, et array med alle brugte TimeStamps
	 */
	public TimeStamp[] getAllTimeStamp() {
		TimeStamp[] tid;
		tid = new TimeStamp[super.getBehandling().getDelBehandlinger().size() + 1];
		for (int i = 0; i <= super.getBehandling().getDelBehandlinger().size(); i++) {
			if (i < startTidListe.size()) {
				tid[i] = startTidListe.get(i);
			} else {
				tid[i] = null;
			}
		}
		return tid;
	}

	/**
	 * Retunere det næste index for delbehandling
	 * @return, index af næste delbehandling.
	 */
	public int getNextDelBehandling() {
		return naesteDelbehandling;
	}

}
